/**
 * 
 */
package org.simplextensions.scanner.impl;

import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ClassFile;
import javassist.bytecode.annotation.Annotation;
import org.simplextensions.scanner.ClassScannerBundle;
import org.simplextensions.scanner.IClassScanner;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * 
 * @author Tomasz Krzyzak, <a
 *         href="mailto:tomasz.krzyzak@gmail.com">tomasz.krzyzak@gmail.com</a>
 * @since 31-08-2010 21:21:15
 */
public class ClasspathScanner {

	public ClasspathScanner() {
	}

	public void scannClassPath(ClassScannerBundle bundle) {
		long a = System.nanoTime();
		Iterator<ClassFile> iterator = bundle.classFileIterator();
		Collection<ClassFile> classFiles = new LinkedList<ClassFile>();
		while (iterator.hasNext()) {
			ClassFile next = iterator.next();
			classFiles.add(next);
		}
		System.out.println(bundle.getName() + ": " + (System.nanoTime() - a) / 1000000.0 + "ms");
		scannClassFile(bundle, classFiles);
	}

	/**
	 * @param bundle
	 * @param classFiles
	 */
	private void scannClassFile(ClassScannerBundle bundle, Collection<ClassFile> classFiles) {
		List<IClassScanner> scanListeners2 = bundle.getScanListeners();
		for (IClassScanner cs : scanListeners2) {
			for (ClassFile cf : classFiles) {
				executeClassScanner(bundle, cf, cs, (AnnotationsAttribute) cf.getAttribute(AnnotationsAttribute.visibleTag));
				executeClassScanner(bundle, cf, cs, (AnnotationsAttribute) cf.getAttribute(AnnotationsAttribute.invisibleTag));
			}
		}
	}

	private void executeClassScanner(ClassScannerBundle bundle, ClassFile classFile, IClassScanner cs, AnnotationsAttribute attributeInfo) {
		if (attributeInfo != null)
			for (Annotation a : attributeInfo.getAnnotations()) {
				cs.scanClass(classFile, a);
			}
	}

}
